package com.wangshili.sys.service.Impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.wangshili.common.bo.PageObject;
import com.wangshili.common.exception.ServiceException;
import com.wangshili.pojo.common.vo.CheckBox;
import com.wangshili.pojo.sys.entity.SysLog;
import com.wangshili.pojo.sys.entity.SysRole;
import com.wangshili.sys.dao.SysRoleDao;
import com.wangshili.sys.dao.SysRoleMenuDao;
import com.wangshili.sys.service.SysRoleService;
import com.wangshili.sys.vo.SysRoleMenu;

/**
 * 角色管理业务层
 * @author wangshili
 *
 */
//问题：每个都需要配置这些是不是有些麻烦。这些值有没有经典值，比如超时时间
//将事务配在类上，所有的方法都会按照该配置的事务执行
@Transactional( 
	//value 和 transactionManager 属性
		//它们两个是一样的意思。当配置了多个事务管理器时，可以使用该属性指定选择哪个事务管理器。
	//事务的超时时间，默认值为-1,表示没有超时显示。如果配置了具体时间,则超过该时间限制但事务还没有完成，则自动回滚事务。
	timeout = 30,
	//指定事务是否为只读事务，默认值为 false；为了忽略那些不需要事务的方法，比如读取数据，可以设置 read-only 为 true。
	readOnly = false,
	//isolation事务的隔离级别，默认值采用 DEFAULT
	isolation = Isolation.READ_COMMITTED,
	//用于指定能够触发事务回滚的异常类型,一般是顶级异常就可以保证回滚，如果有多个异常类型需要指定，各类型之间可以通过逗号分隔。
	rollbackFor = Throwable.class,
	//用于指定能够触发事务不回滚的异常类型，就是如果出现该异常，事务不需要回滚，如果有多个异常类型需要指定，各类型之间可以通过逗号分隔。
	//noRollbackFor = Throwable.class,
	//事务的传播行为,REQUIRED如果存在事务，则加入，不存在就新建事务()
	propagation = Propagation.REQUIRED)
@Service
public class SysRoleServiceImpl implements SysRoleService {
	
	/**
	 * 角色持久层接口
	 */
	@Autowired
	private SysRoleDao sysRoleDao;
	
	@Autowired
	private SysRoleMenuDao sysRoleMenuDao;
	
	/**
	 * 根据名字统计出现次数，name可以为空
	 */
	@Transactional(readOnly = true)//不需要事务
	@Override
	public int countRoleByName(String name) {
		int count = sysRoleDao.countRoleByName(name);
		return count;
	}
	
	/**
	 * 根据当前页计算起始位置
	 */
	@Override
	public PageObject<SysRole> listRoleObjects(String name, Integer pageCurrent) {
		//1.先进行数据校验
		if(pageCurrent<1)throw new IllegalArgumentException("当前页下标不符合");//当前页下标不能为0
		int count = countRoleByName(name);//多少条记录
		if(count<1)throw new ServiceException("未找到相关记录");
		//2.设置每页显示的数据量和计算起始位置
		int pageSize = 10;//每页数据量设为10行
		int startIndex = (pageCurrent-1)*10;//分页起始位置
		try {
			List<SysRole> listRoleObjects = 
					sysRoleDao.listRoleObjects(name, startIndex, pageSize);
			return new PageObject<SysRole>(pageCurrent,pageSize,count,listRoleObjects);
		} catch (Exception e) {
			throw new ServiceException("查询异常，请重试");
		}
	}
	
	/**
	 * 先插入角色数据，再根据返回的id插入关系表
	 */
	@Override
	public int insertRoleMenuObject(SysRole entity, Integer... ids) {
		if(entity == null)throw new ServiceException("数据不能为空");
		//1.插入角色数据
		try {
			sysRoleDao.insertRoleObject(entity);
			sysRoleMenuDao.insertRoleMenu(entity.getId(), ids);
		} catch (Exception e) {
			e.printStackTrace();
			throw new ServiceException("插入角色数据失败，请重试");
		}	
		return 0;
	}
	
	/**
	 * 根据id删除角色信息
	 */
	@Override
	public int deleteRoleObjectById(Integer id) {
		if(id==null || id<1)throw new ServiceException("提交的数据异常");
		int rows =0;
		try {
			 rows = sysRoleDao.deleteRoleObjectById(id);
			 if(rows<1)throw new ServiceException("要删除的信息可能不存在");
			return rows;
		} catch (Exception e) {
			throw new ServiceException("删除失败，请重试");
		}

	}
	
	/**
	 * 根据id查找角色信息和关系表
	 */
	@Override
	public SysRoleMenu findObjectById(Integer id) {
		SysRoleMenu findObjectById = sysRoleDao.findObjectById(id);
		System.out.println(findObjectById);
		return findObjectById;
	}
	
	/**
	 * 更新数据
	 * @param entity
	 * @return
	 */
	@Override
	public int updateRoleObject(SysRole entity) {
		if(entity==null)throw new ServiceException("数据不能为空");
		try {
			int rows = sysRoleDao.updateRoleObject(entity);
			if(rows<1)throw new ServiceException("此记录可能不存在");
		} catch (Exception e) {
			throw new ServiceException("更新失败，请重试");
		}
		return 0;
	}
	/**
	 * 查询所有的角色信息，只返回id和name并用CheckBox封装
	 * @return
	 */
	@Override
	public List<CheckBox> findCheckBoxObjects() {
		List<CheckBox> checkBox = 
				sysRoleDao.findCheckBoxObjects();
		if(checkBox==null || checkBox.size()<1)
			throw new ServiceException("未找到角色信息");
		return checkBox;
	}

}
